﻿using HtmlAgilityPack;
using Manhua3.Common;
using Manhua3.SQLiteTable;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Manhua3.Helper;
using Manhua3.Client;

namespace Manhua3.Provider
{
    public class SFACGProvider : IComicProvider
    {
        private const string latest_url = "http://comic.sfacg.com/WeeklyUpdate/";
        private const string base_url = "http://{0}.sfacg.com/Utility/{1}/{2}.js";
        private static string[] server = new string[]{ "coldpic", "hotpic", "pic3" };


        private static DateTime lastUpdatedTime = DateTime.MinValue;

        public int TopCount
        {
            get { return 40; }
        }

        public string ProviderName
        {
            get { return "sfacg"; }
        }

        public async Task SaveLatestComicsAsync(bool cache)
        {
            if (cache)
            {
                if ((DateTime.Now - lastUpdatedTime).TotalMinutes < 10)
                {
                    return;
                }
            }

            lastUpdatedTime = DateTime.Now;

            using (DbContext context = new DbContext())
            {
                context.BeginTransaction();

                try
                {
                    HtmlDocument html = await XHttpClient.GetHtmlDocumentAsync(latest_url);

                    List<HtmlNode> tables = new List<HtmlNode>();

                    var nodes = html.DocumentNode.GetElementByClass("font_red gray_link1 space10px");
                    foreach (var node in nodes)
                    {
                        tables.AddRange(node.GetElements("table"));
                    }
                    
                    foreach (var table in tables)
                    {
                        var a = table.GetElements("a");
                        var img = a[0].GetElement("img");
                        var td = table.GetElements("td");

                        var comic = await context.GetComic(a[1].InnerText, this.ProviderName);
                        if (comic == null)
                        {
                            comic = new SQLiteComic() 
                            {
                                ChapterUrl = a[0].GetAttributeValue("href", string.Empty),
                                CoverUrl = img.GetAttributeValue("src", string.Empty),
                                Title = a[1].InnerText,
                                Provider = this.ProviderName,
                            };

                            await context.InsertAsync(comic);
                        }

                        var chapter = await context.GetChapter(td[2].InnerText, comic.Id);
                        if (chapter == null)
                        {
                            await context.InsertChapter(td[2].InnerText, comic.Id, DateTime.Now);
                        }
                    }

                    context.Commit();
                }
                catch
                {
                    context.Rollback();
                    throw;
                }
            }
        }

        public async Task SavePagesAsync(int chapterId)
        {
            using (DbContext context = new DbContext())
            {
                var chapter = await context.GetAsync<SQLiteChapter>(chapterId);
                if (chapter == null)
                    throw new ArgumentNullException("章节不存在");

                context.BeginTransaction();

                try
                {
                    string url = chapter.Url;
                    if (!url.EndsWith("/"))
                    {
                        url += "/";
                    }

                    var m = Regex.Matches(url, @"/\d+");

                    HtmlDocument html = await XHttpClient.GetHtmlDocumentAsync(
                        string.Format(
                        base_url,
                        server.Where((k) =>
                        {
                            return chapter.Url.IndexOf(k) != -1;
                        }).First()
                        , m[0].Value.Trim('/'), m[1].Value.Trim('/')));

                    Regex regex = new Regex(@"picAy.*?;");
                    m = regex.Matches(html.DocumentNode.WriteContentTo());

                    for (int i = 1; i < m.Count; i++)
                    {
                        if (m[i].Value != null)
                        {
                            SQLitePage page = new SQLitePage()
                            {
                                ChapterId = chapter.Id,
                                Page = i,
                                Url = Regex.Match(m[i].Value, "\".*\"").Value.Trim('"'),
                            };

                            await context.InsertAsync(page);
                        }
                    }

                    chapter.TotalPage = m.Count - 1;
                    if (chapter.TotalPage <= 0)
                        throw new Exception("获取失败");
                    await context.UpdateAsync(chapter);

                    context.Commit();
                }
                catch
                {
                    context.Rollback();
                    throw;
                }
            }
        }

        public async Task SaveChaptersAsync(int comicId)
        {
            using (DbContext context = new DbContext())
            {
                var comic = await context.GetAsync<SQLiteComic>(comicId);
                if (comic == null) throw new ArgumentNullException("comic");

                context.BeginTransaction();

                try
                {
                    HtmlDocument html = await XHttpClient.GetHtmlDocumentAsync(comic.ChapterUrl);

                    var ul = html.DocumentNode.GetElementByClass("serialise_list Blue_link2").FirstOrDefault();
                    var li = ul.GetElements("a");

                    // 反转序列，这样能保证先插入数据库的章节是旧章节
                    li.Reverse();

                    DateTime timestamp = new DateTime(1970, 1, 1);

                    for (int i = 0; i < li.Count; i++)
                    {
                        var chapter = await context.GetChapter(li[i].InnerText, comic.Id);
                        if (i == li.Count - 1)
                        {
                            if (chapter == null)
                            {
                                chapter = await context.GetChapterLatest(comic.Id);
                            }
                        }

                        if (chapter == null)
                        {
                            await context.InsertChapter(
                                li[i].InnerText,
                                comic.Id,
                                timestamp,
                                li[i].GetAttributeValue("href", string.Empty));
                        }
                        else
                        {
                            chapter.Url = li[i].GetAttributeValue("href", string.Empty);
                            await context.UpdateAsync(chapter);
                        }
                    }
                    
                    context.Commit();
                }
                catch
                {
                    context.Rollback();
                    throw;
                }

                // serialise_list Blue_link2
            }
        }

        public override string ToString()
        {
            return ProviderName;
        }
    }
}
